//
// Created by jack on 2021/2/7.
//

#include "weilapb_defines.h"

#include <WL.Service.pb.h>

#include "weilapb_datafuns.h"

#include "weilapb_internal.h"

PBEncResult weilapb_buildFriendReq(PB_UINT16 commandId, WL_Friend_FriendMessage* pParam) {
    PBEncResult                pbResult;
    WL_Service_ServiceMessage* pServiceMessage =
        weilapb_buildServiceMsg(WL_Service_ServiceID_SERVICE_FRIEND, commandId, WL_Service_CommandType_COMMAND_REQUEST);

    memset(&pbResult, 0, sizeof(PBEncResult));
    pbResult.message = weilapb_getMessageByCommandId(WL_Service_ServiceID_SERVICE_FRIEND, commandId);
    if (pServiceMessage) {
        pServiceMessage->has_friendMessage = true;
        memcpy(&pServiceMessage->friendMessage, pParam, sizeof(WL_Friend_FriendMessage));
        if (weilapb_encodeWeilaMsg(pServiceMessage, &pbResult)) {
            PB_FREE(pServiceMessage);
            return pbResult;
        } else {
            PB_FREE(pServiceMessage);
            pbResult.errCode = ERR_ENCODE;
        }
    } else {
        pbResult.errCode = ERR_OUT_OF_MEMORY;
    }

    return pbResult;
}

PBEncResult weilapb_buildGetFriendInfoReq(PB_UINT64 latestTimestamp) {
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;

    wlFriendFriendMessage.has_reqGetFriendInfo               = true;
    wlFriendFriendMessage.reqGetFriendInfo.has_latestUpdated = true;
    wlFriendFriendMessage.reqGetFriendInfo.latestUpdated     = latestTimestamp;

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_COMMAND_GET_FRIENDINFO, &wlFriendFriendMessage);
}

PBEncResult weilapb_buildGetFriendUserInfoReq(PB_UINT32* pUserIdList, PB_UINT32 listCount) {
    PBFieldData             userIdListField;
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;

    wlFriendFriendMessage.has_reqGetFriendUserInfo = true;
    weilapb_initEncDataItem(&userIdListField, PB_DATA_TYPE_ARRAY_UINT32, listCount, pUserIdList);
    weilapb_setDecCallback(&userIdListField, &wlFriendFriendMessage.reqGetFriendUserInfo.userIds, PB_NULL);

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_COMMAND_GET_FRIEND_USERINFO, &wlFriendFriendMessage);
}

PBEncResult weilapb_buildGetFriendInviteInfoReq(PB_UINT64 latestTimestamp) {
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;

    wlFriendFriendMessage.has_reqGetFriendInviteInfo               = true;
    wlFriendFriendMessage.reqGetFriendInviteInfo.has_latestUpdated = true;
    wlFriendFriendMessage.reqGetFriendInviteInfo.latestUpdated     = latestTimestamp;

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_COMMAND_GET_FRIEND_INVITEINFO,
                                  &wlFriendFriendMessage);
}

PBEncResult weilapb_buildFriendInviteReq(PB_UINT32 inviteeId, PB_CHAR* pDetail, PB_CHAR* pRemark) {
    PBFieldData             detailField;
    PBFieldData             remarkField;
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;

    wlFriendFriendMessage.has_reqFriendInvite           = true;
    wlFriendFriendMessage.reqFriendInvite.has_inviteeId = true;
    wlFriendFriendMessage.reqFriendInvite.inviteeId     = inviteeId;

    if (pDetail) {
        weilapb_initDecDataItem(&detailField, PB_DATA_TYPE_FIXED_SIZE_STRING, strlen(pDetail), pDetail);
        weilapb_setDecCallback(&detailField, &wlFriendFriendMessage.reqFriendInvite.detail, PB_NULL);
    }

    if (pRemark) {
        weilapb_initDecDataItem(&remarkField, PB_DATA_TYPE_FIXED_SIZE_STRING, strlen(pRemark), pRemark);
        weilapb_setDecCallback(&remarkField, &wlFriendFriendMessage.reqFriendInvite.remark, PB_NULL);
    }

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_COMMAND_FRIEND_INVITE, &wlFriendFriendMessage);
}

PBEncResult weilapb_buildAnswerFriendInviteReq(PB_UINT32 invitorId, PB_UINT32 answerStatus, PB_CHAR* pRemark) {
    PBFieldData             remarkField;
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;

    wlFriendFriendMessage.has_reqAnswerFriendInvite           = true;
    wlFriendFriendMessage.reqAnswerFriendInvite.has_inviterId = true;
    wlFriendFriendMessage.reqAnswerFriendInvite.inviterId     = invitorId;

    wlFriendFriendMessage.reqAnswerFriendInvite.has_status = true;
    wlFriendFriendMessage.reqAnswerFriendInvite.status     = answerStatus;

    if (pRemark) {
        weilapb_initEncDataItem(&remarkField, PB_DATA_TYPE_FIXED_SIZE_STRING, strlen(pRemark), pRemark);
        weilapb_setEncCallback(&remarkField, &wlFriendFriendMessage.reqAnswerFriendInvite.remark, PB_NULL);
    }

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_COMMAND_ANSWER_FRIEND_INVITE,
                                  &wlFriendFriendMessage);
}

PBEncResult weilapb_buildDeleteFriendReq(PB_UINT32 userId) {
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;

    wlFriendFriendMessage.has_reqDeleteFriend        = true;
    wlFriendFriendMessage.reqDeleteFriend.has_userId = true;
    wlFriendFriendMessage.reqDeleteFriend.userId     = userId;

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_COMMAND_DELETE_FRIEND, &wlFriendFriendMessage);
}

PBEncResult weilapb_buildChangeFriendInfoReq(PB_UINT32 friendId, PBChangeFriendInfo* pChangeFriendInfo) {
    PBFieldData             remarkField;
    PBFieldData             labelField;
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;

    wlFriendFriendMessage.has_reqChangeFriendInfo        = true;
    wlFriendFriendMessage.reqChangeFriendInfo.has_userId = true;
    wlFriendFriendMessage.reqChangeFriendInfo.userId     = friendId;

    if (pChangeFriendInfo) {
        if (pChangeFriendInfo->changeRemark) {
            weilapb_initEncDataItem(
                &remarkField, PB_DATA_TYPE_FIXED_SIZE_STRING, MAX_NORMAL_STRING_LEN, pChangeFriendInfo->remark);
            weilapb_setEncCallback(&remarkField, &wlFriendFriendMessage.reqChangeFriendInfo.remark, PB_NULL);
        }

        if (pChangeFriendInfo->changeLabel) {
            weilapb_initEncDataItem(
                &labelField, PB_DATA_TYPE_FIXED_SIZE_STRING, MAX_SHORT_STRING_LEN, pChangeFriendInfo->label);
            weilapb_setEncCallback(&labelField, &wlFriendFriendMessage.reqChangeFriendInfo.label, PB_NULL);
        }

        if (pChangeFriendInfo->changeLocationShared) {
            wlFriendFriendMessage.reqChangeFriendInfo.has_locationShare = true;
            wlFriendFriendMessage.reqChangeFriendInfo.locationShare     = pChangeFriendInfo->locationShared;
        }

        if (pChangeFriendInfo->changeRecvStatus) {
            wlFriendFriendMessage.reqChangeFriendInfo.has_shieldStatus = true;
            wlFriendFriendMessage.reqChangeFriendInfo.shieldStatus     = pChangeFriendInfo->recvStatus;
        }

        if (pChangeFriendInfo->changeTts) {
            wlFriendFriendMessage.reqChangeFriendInfo.has_tts = true;
            wlFriendFriendMessage.reqChangeFriendInfo.tts     = pChangeFriendInfo->Tts;
        }
    }

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_COMMAND_CHANGE_FRIENDINFO, &wlFriendFriendMessage);
}

PBEncResult weilapb_buildGetFriendBlacklistReq(PB_UINT32 pageIndex, PB_UINT32 pageSize) {
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;

    wlFriendFriendMessage.has_reqGetFriendBlackList           = true;
    wlFriendFriendMessage.reqGetFriendBlackList.has_pageIndex = true;
    wlFriendFriendMessage.reqGetFriendBlackList.pageIndex     = pageIndex;

    wlFriendFriendMessage.reqGetFriendBlackList.has_pageSize = true;
    wlFriendFriendMessage.reqGetFriendBlackList.pageSize     = pageSize;

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_COMMAND_GET_BLACKLIST, &wlFriendFriendMessage);
}

PBEncResult weilapb_buildChangeFriendBlacklistReq(PB_UINT32* pUserIdList, PB_UINT32 listCount, PB_UINT32 status) {
    PBFieldData             userIdListField;
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;

    wlFriendFriendMessage.has_reqChangeFriendBlackList      = true;
    wlFriendFriendMessage.reqChangeFriendBlackList.has_type = true;
    wlFriendFriendMessage.reqChangeFriendBlackList.type     = status;

    weilapb_initEncDataItem(&userIdListField, PB_DATA_TYPE_ARRAY_UINT32, listCount, pUserIdList);
    weilapb_setEncCallback(&userIdListField, &wlFriendFriendMessage.reqChangeFriendBlackList.userIds, PB_NULL);

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_COMMAND_CHANGE_BLACKLIST, &wlFriendFriendMessage);
}

PBEncResult weilapb_buildGetOnlineFriendReq() {
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;

    wlFriendFriendMessage.has_reqGetOnlineFriend = true;

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_COMMAND_GET_ONLINE_FRIEND, &wlFriendFriendMessage);
}

PBEncResult weilapb_buildEmbeddedGetFriendInfo(PB_UINT64  latestUpdated,
                                               PB_UINT32* pUserIdList,
                                               PB_UINT32  listCount,
                                               PB_UINT32  limit) {
    WL_Friend_FriendMessage wlFriendFriendMessage = WL_Friend_FriendMessage_init_zero;
    PBFieldData             userIdListField;

    wlFriendFriendMessage.has_reqEmbeddedGetFriendInfo               = true;
    wlFriendFriendMessage.reqEmbeddedGetFriendInfo.has_latestUpdated = true;
    wlFriendFriendMessage.reqEmbeddedGetFriendInfo.latestUpdated     = latestUpdated;

    if (pUserIdList && listCount) {
        weilapb_initEncDataItem(&userIdListField, PB_DATA_TYPE_ARRAY_UINT32, listCount, pUserIdList);
        weilapb_setEncCallback(&userIdListField, &wlFriendFriendMessage.reqEmbeddedGetFriendInfo.userIds, PB_NULL);
    }
    wlFriendFriendMessage.reqEmbeddedGetFriendInfo.has_limit = true;
    wlFriendFriendMessage.reqEmbeddedGetFriendInfo.limit     = limit;

    return weilapb_buildFriendReq(WL_Friend_FriendCommandId_FRIEND_EMBEDDED_COMMAND_GET_FRIENDINFO,
                                  &wlFriendFriendMessage);
}
